package reflect;

/**
 * 练习：获得反射的三种方式
 */

public class TestDemo {
    public static void main(String[] args) throws ClassNotFoundException {
        // 每个类对应一个Class队形由JVM生成（有且仅有一个）
        // 获得反射的三种方式
        // 1. 《直接通过》 类的名称.class
        // 该方法最为安全可靠，程序性能更高，这说明任何一个类都有一个隐含的静态成员变量 class
        Class c1 = Student.class;

        // 2.通过类的任何一个实例化对象，调用getClass（）方法
        Student s1 = new Student();
        Class c2 = s1.getClass();

        // p 编译期和运行时都是Person类型
        Person p = new Person();
        // p1编译器是Person类型，运行时就编程了Student类型
        Person p1 = s1;  // 向上转型的类运行时生成的Class对象是原来它子类对象的Class对象。
        System.out.println(p1.getClass()); // 结果： class reflect.Student

        // 通过Class的forName(“包名.类名 也就是 类的全路径名”)静态方法，这是用的最多的方法
        Class c3 = Class.forName("reflect.Student"); // 但可能会抛出ClassNotFoundException异常，所以要在方法前面通过throws抛出
        // 或者
        Class c4 = null;
        try {
            c4 = Class.forName("reflect.Student");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        // 一个类在JVM中有且仅有一个Class对象（实例）
        // 通过equals()方法比较发现上面产生的三个Class对象都是同一个
        System.out.println(c1.equals(c2));
        System.out.println(c2.equals(c3)); //true  true
    }
}

class Person {
    private String name = "wang";
    public int age = 13;
    public Person() {
        System.out.println("Person类的无参构造方法");
    }

    public void play() {
        System.out.println("public func");
    }

    private void happy() {
        System.out.println("private func");
    }
}


class Student extends Person {
    // 私有属性name
    private String name = "cup";
    private double height = 180.5;
    // 公有属性age
    public int age = 19;

    // 无参构造方法
    public Student() {
        System.out.println("Student类的无参构造方法");
    }

    // 私有的有参构造方法
    private Student(String name, int age) {
        this.name = name;
        this.age = age;
        System.out.println("Student的私有的有参构造方法");
    }

    public Student(String name, double height) {
        this.name = name;
        this.height = height;
    }

    private void eat() {
        System.out.println("He is eating");
    }

    public void sleep() {
        System.out.println("He is a pig");
    }

    private void function(String str) {
        System.out.println(str);
    }

    public static void staticFunc() {
        System.out.println("静态方法");
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
